package com.ys.controller.api.finance;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bo.dto.NameValueDto;
import com.ys.config.MenuId;
import com.ys.entity.finance.TcwWanliPaymentReturn;
import com.ys.entity.finance.TcwWanliPaymentReturnItem;
import com.ys.entity.sys.YsCol;
import com.ys.service.finance.TcwWanliPaymentReturnService;
import com.ys.service.flow.YspTaskService;
import com.ys.service.sys.CommonApiService;
import com.ys.service.sys.PdfService;
import com.ys.service.sys.UploadService;
import com.ys.util.DateUtil;
import com.ys.util.ExportExcelUtils;
import com.ys.util.RedisUtil;
import com.ys.util.admin.ConditionUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;

/**
 * 万里汇预付款退回
 */
@Controller
@RequestMapping("/api/inter/tcwWanliPaymentReturn")
public class ApiInterTcwWanliPaymentReturnController {
    private static final Logger logger = LoggerFactory.getLogger(ApiInterTcwWanliPaymentReturnController.class);

    @Autowired
    private CommonApiService<TcwWanliPaymentReturn> commonApiService;

    @Autowired
    private TcwWanliPaymentReturnService tcwWanliPaymentReturnService;

    @Autowired
    private YspTaskService yspTaskService;


    @Autowired
    private PdfService pdfService;

    @RequiresPermissions("tcwWanliPaymentReturn:view")
    @RequestMapping("/search")
    @ResponseBody
    public LayuiTableVoJA search(@ModelAttribute TcwWanliPaymentReturn cond,String conditions){
        String _ys_createUserInfo = ConditionUtil.getConditionValue(conditions, "_ys_createUserInfo");
        if (_ys_createUserInfo != null && _ys_createUserInfo.length() != 0) {
            cond.where("t2.UserId LIKE '%" + _ys_createUserInfo + "%'" + " OR  t2.UserName LIKE '%" + _ys_createUserInfo + "%'");
        }
        cond.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
                .addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd hh:mm:ss') AS updateTime1")//审核时间
        .addLeftJoin("TS_UserChange t2 on  A.CreateChangeId = t2.id")
                .addField("CONCAT(t2.UserId,'/', t2.UserName) as _ys_createUserInfo")
        .addLeftJoin("TCW_DepositPlatform tda ON tda.id = A.DepositPlatformId")//收款账户平台
                .addField("tda.id AS depositPlatformId,tda.platformName AS platformName,tda.code AS depositPlatformCode,tda.name AS depositPlatformName")
        .addLeftJoin("TB_CompanyInfo tci ON tci.vid = tda.CompanyVid ")//公司
                .addField("tci.vname AS companyName")
        .addLeftJoin("TCW_WanliPaymentReturnItem tce ON tce.WanliPaymentReturnBid = A.Bid ")//预付款退回子件
                .addField("tce.thCurrencyCode AS thCurrencyCode,tce.thAmount AS thAmount,tce.zfAmount AS zfAmount,tce.exchangeRate AS exchangeRate" +
                        ",tce.serviceCharge AS serviceCharge,tce.statePay")
        .addLeftJoin("TCW_PaymentReturnItem tpr ON tpr.id = tce.PaymentReturnItemId")//预付款申请详情
                .addField("tpr.paymentReturnBid AS paymentReturnBid, tpr.vJyLx AS vJyLx,tpr.accountType AS accountType")
        .addLeftJoin("THR_OperateCompanyBankInfo ocbi ON ocbi.id = tpr.companyBankId")//银行账户
                .addField("ocbi.vyhzhmc AS vyhzhmc,ocbi.vkhh AS vkhh,ocbi.vyhzh AS vyhzh,ocbi.vlhh AS vlhh")
        .addLeftJoin("THR_OperateCompanyApply THRO ON THRO.vgsbm = ocbi.vgsbm")//运营公司
                .addField("THRO.vgsjc AS vgsjc,THRO.vgsbm AS vgsbm,THRO.CUser AS cUser")
        	    .addField("(SELECT top 1 tdpa.Vyhzh  FROM TCW_DepositPlatformAccount tdpa WHERE tdpa.Vgsbm = THRO.Vgsbm) AS depositPlatformAccountCode");
        cond = commonApiService.dataAuth(MenuId.TCW_WanliPaymentReturn, cond);
        return commonApiService.searchLay(cond);
    }


    /**
     * 新增
     */
    @RequiresPermissions("tcwWanliPaymentReturn:add")
    @RequestMapping("/toAdd")
    @ResponseBody
    public R toAdd(HttpServletRequest request, @RequestParam Map<String, Object> params,String subData
    ) {
        try {
            logger.info("万里汇预付款退回新增传参：" + params);
            //修改
            return tcwWanliPaymentReturnService.add(params,subData);
        } catch (Exception e) {
            logger.error("万里汇预付款退回新增出错：", e.getMessage(), e);
            return R.error(e.getMessage());
        }
    }


    /**
     * 修改
     */
    @RequiresPermissions("tcwWanliPaymentReturn:add")
    @RequestMapping("/toEdit")
    @ResponseBody
    public R toEdit(HttpServletRequest request, @RequestParam Map<String, Object> params,String subData
    ) {
        try {
            logger.info("万里汇预付款退回修改传参：" + params);
            //修改
            return tcwWanliPaymentReturnService.edit(params,subData);
        } catch (Exception e) {
            logger.error("万里汇预付款退回修改出错：", e.getMessage(), e);
            return R.error(e.getMessage());
        }
    }


    @PostMapping("/flowPass")
    @ResponseBody
    public R flowPass(HttpServletRequest request, Long id){
        try {
            return tcwWanliPaymentReturnService.flowPass(id, ShiroUtils.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }
    }

    /**
     * 流转退回
     */
    @PostMapping("/flowRefuse")
    @ResponseBody
    public R flowRefuse(HttpServletRequest request, Long id, String reason){
        TcwWanliPaymentReturn entity = new TcwWanliPaymentReturn().setId(id).queryFirst();
        String bid = entity.getBid();
        try {
            //是否有支付过的数据 不允许回退
            if (new TcwWanliPaymentReturnItem().setWanliPaymentReturnBid(bid).where("A.statePay = 1 OR A.statePay = 2").count() != 0){
                return R.error("数据中执行状态已操作支付功能,不允许退回!");
            }
            return yspTaskService.flowRefuse(bid, reason, ShiroUtils.getUserId());
        } catch (Exception e) {
            logger.error("万里汇万里汇预付款退回驳回出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        }
    }

    /**
     * 流转驳回
     */
    @PostMapping("/flowInit")
    @ResponseBody
    public R flowInit(HttpServletRequest request, Long id, String reason){
        TcwWanliPaymentReturn entity = new TcwWanliPaymentReturn().setId(id).queryFirst();
        String bid = entity.getBid();
        try {
            //是否有支付过的数据 不允许回退
            if (new TcwWanliPaymentReturnItem().setWanliPaymentReturnBid(bid).where("A.statePay = 1 OR A.statePay = 2").count() != 0){
                return R.error("数据中执行状态已操作支付功能,不允许驳回!");
            }
            return yspTaskService.flowInit(bid, reason, ShiroUtils.getUserId());
        } catch (Exception e) {
            logger.error("万里汇万里汇预付款退回驳回出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        }
    }

    /**
     * 删除
     */
    @RequestMapping("/toDel")
    @ResponseBody
    public R del(HttpServletRequest request, Long id){
        try {
            return tcwWanliPaymentReturnService.del(id);
        } catch (Exception e) {
            logger.error("删除万里汇万里汇预付款退回出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        }
    }


    /**
     * 导出
     */
    @RequestMapping("/export")
    @ResponseBody
    public R export(@ModelAttribute TcwWanliPaymentReturn cond, String conditions){
        try {
            cond.setPage(0).setSize(999999);
            String _ys_createUserInfo = ConditionUtil.getConditionValue(conditions, "_ys_createUserInfo");
            if (_ys_createUserInfo != null && _ys_createUserInfo.length() != 0) {
                cond.where("t2.UserId LIKE '%" + _ys_createUserInfo + "%'" + " OR  t2.UserName LIKE '%" + _ys_createUserInfo + "%'");
            }
            cond.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
                    .addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd hh:mm:ss') AS updateTime1")//审核时间
                    .addLeftJoin("TS_UserChange t2 on  A.CreateChangeId = t2.id")
                    .addField("CONCAT(t2.UserId,'/', t2.UserName) as _ys_createUserInfo")
                    .addLeftJoin("TCW_DepositPlatform tda ON tda.id = A.DepositPlatformId")//收款账户平台
                    .addField("tda.id AS depositPlatformId,tda.platformName AS platformName,tda.code AS depositPlatformCode,tda.name AS depositPlatformName")
                    .addLeftJoin("TB_CompanyInfo tci ON tci.vid = tda.CompanyVid ")//公司
                    .addField("tci.vname AS companyName")
                    .addLeftJoin("TCW_WanliPaymentReturnItem tce ON tce.WanliPaymentReturnBid = A.Bid ")//预付款退回子件
                    .addField("tce.thCurrencyCode AS thCurrencyCode,tce.thAmount AS thAmount,tce.zfAmount AS zfAmount,tce.exchangeRate AS exchangeRate" +
                            ",tce.serviceCharge AS serviceCharge,tce.statePay")
                    .addLeftJoin("TCW_PaymentReturnItem tpr ON tpr.id = tce.PaymentReturnItemId")//预付款申请详情
                    .addField("tpr.paymentReturnBid AS paymentReturnBid, tpr.vJyLx AS vJyLx,tpr.accountType AS accountType")
                    .addLeftJoin("THR_OperateCompanyBankInfo ocbi ON ocbi.id = tpr.companyBankId")//银行账户
                    .addField("ocbi.vyhzhmc AS vyhzhmc,ocbi.vkhh AS vkhh,ocbi.vyhzh AS vyhzh,ocbi.vlhh AS vlhh")
                    .addLeftJoin("THR_OperateCompanyApply THRO ON THRO.vgsbm = ocbi.vgsbm")//运营公司
                    .addField("THRO.vgsjc AS vgsjc,THRO.vgsbm AS vgsbm,THRO.CUser AS cUser")
                    .addField("(SELECT top 1 tdpa.Vyhzh  FROM TCW_DepositPlatformAccount tdpa WHERE tdpa.Vgsbm = THRO.Vgsbm) AS depositPlatformAccountCode");

            cond = commonApiService.dataAuth(MenuId.TCW_WanliPaymentReturn, cond);
            //获取菜单字段数据
            List<YsCol> listField = new YsCol()
                    .setMenuId(MenuId.TCW_WanliPaymentReturn)
                    .setFrontShow(1)
                    .setOrderby("A.SortNo asc")
                    .queryList();
            //获取数据
            List<Map<String, Object>> listData = cond.queryMap();
            //处理数据
            ExportExcelUtils<TcwWanliPaymentReturn> util = new ExportExcelUtils<>(new TcwWanliPaymentReturn());
            String toFilePath = util.exportExcel(listData, listField, "万里汇万里汇预付款退回报表");
            UploadService.UploadDto dto = commonApiService.uploadLocalToServer(toFilePath);
            return R.ok(dto.getUrl());
        }catch (Exception e){
            logger.error("导出出错：",e.getMessage(),e);
            return R.error("导出失败，请稍后重试！");
        }
    }

    /**
     * 转入万里汇
     * @return
     */
    @RequestMapping("/zrWanli")
    @ResponseBody
    public R zrWanli(String id){
        if (id == null){
            return R.error("单据未保存,请保存后再操作!");
        }
        try {
            R r = tcwWanliPaymentReturnService.zrWanli(id);
            return r;
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    /**
     * 打印万里汇预付款退回
     * @param request
     * @param bid
     * @return
     * @throws Exception
     */
    @RequestMapping("/exportdy")
    @ResponseBody
    public R exportdy(HttpServletRequest request,@RequestParam("bid") String bid) throws Exception{
        Map tcwWanliPaymentReturn = new TcwWanliPaymentReturn().setBid(bid)
        .addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
                .addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd hh:mm:ss') AS updateTime1")//审核时间
                .addLeftJoin("TS_UserChange t2 on  A.CreateChangeId = t2.id")
                .addField("CONCAT(t2.UserId,'/', t2.UserName) as _ys_createUserInfo,t2.deptName deptName")
                .addLeftJoin("TCW_DepositPlatform tda ON tda.id = A.DepositPlatformId")//收款账户平台
                .addField("tda.id AS depositPlatformId,tda.platformName AS platformName,tda.code AS depositPlatformCode,tda.name AS depositPlatformName")
                .queryFirstMap();

        BigDecimal thAmount = BigDecimal.ZERO;
        //子件数据
        List<Map<String, Object>> sonlist = new TcwWanliPaymentReturnItem()
                .setWanliPaymentReturnBid(bid)
                .addLeftJoin("TCW_PaymentReturnItem tpr ON tpr.id = A.PaymentReturnItemId")//预付款申请详情
                .addField("tpr.paymentReturnBid AS paymentReturnBid, tpr.vJyLx AS vJyLx,tpr.accountType AS accountType")
                .addLeftJoin("THR_OperateCompanyBankInfo ocbi ON ocbi.id = tpr.companyBankId")//银行账户
                .addField("ocbi.vyhzhmc AS vyhzhmc,ocbi.vkhh AS vkhh,ocbi.vyhzh AS vyhzh,ocbi.vlhh AS vlhh")
                .addLeftJoin("THR_OperateCompanyApply THRO ON THRO.vgsbm = ocbi.vgsbm")//运营公司
                .addField("THRO.vgsjc AS vgsjc,THRO.vgsbm AS vgsbm")
                .addField("(SELECT top 1 tdpa.Vyhzhmc  FROM TCW_DepositPlatformAccount tdpa WHERE tdpa.Vgsbm = THRO.Vgsbm) AS depositPlatformAccountCode")
                .queryMap();

        for (Map<String, Object> son : sonlist){
            thAmount = thAmount.add(new BigDecimal(son.get("thAmount").toString()));
        }

        List<NameValueDto> listData = new ArrayList<>();
        listData.add(new NameValueDto("单据编号",bid));
        listData.add(new NameValueDto("申请人",tcwWanliPaymentReturn.get("_ys_createUserInfo").toString()));
        listData.add(new NameValueDto("申请部门",tcwWanliPaymentReturn.get("deptName").toString()));
        listData.add(new NameValueDto("付款账号",tcwWanliPaymentReturn.get("depositPlatformName").toString()+ "/"
                + tcwWanliPaymentReturn.get("depositPlatformCode").toString() +
                "/" + tcwWanliPaymentReturn.get("platformName").toString()));
        listData.add(new NameValueDto("收款账号","预付款退回"));
        listData.add(new NameValueDto("付款类型","运营公司账户"));
        listData.add(new NameValueDto("付款金额",thAmount.toString()));
        listData.add(new NameValueDto("付款说明",tcwWanliPaymentReturn.get("vbz").toString()));
        //时间转换
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse(tcwWanliPaymentReturn.get("createTime").toString());
        String url = pdfService.generatePDF(bid,"万里汇预付款退回",tcwWanliPaymentReturn.get("depositPlatformName").toString(),
                DateUtil.getYYYY_MM_DD_HH_mm_ss(date),listData);
        return R.ok(url);
    }
}
